home *** CD-ROM | disk | FTP | other *** search
- #include "sprite.h"
- #include <globals.h>
- #include "stallowdraw.h"
-
- static short GetMainSlot()
- {
- short mainDeviceRefNum = GetMainDevice()[0]->gdRefNum;
- short mainSlotNumber = AuxDCEHandle(GetDCtlEntry(mainDeviceRefNum))[0]->dCtlSlot;
-
- return mainSlotNumber;
- }
-
- inline short RectHeight(const Rect& r)
- {
- return r.bottom - r.top;
- }
-
- inline short RectWidth(const Rect& r)
- {
- return r.right - r.left;
- }
-
- CSprite::CSprite(CSpriteWorld* theWorld,long id,const Rect& inStart)
- : fLocation(inStart),
- fID(id),
- fWorld(theWorld)
- {
- fWorld->AddSprite(this);
- }
-
-
-
-
-
- CSprite::~CSprite()
- {
- fWorld->RemoveSprite(this);
- }
-
- const Rect* CSprite::GetGameBounds()
- {
- return fWorld->GetSpriteCanvas()->GetBounds();
- }
-
-
- Boolean CSprite::KeyIsDownQ(short k)
- {
- unsigned char km[16];
-
- GetKeys((UInt32*)km);
- return (( (km[k>>3] >> (k & 7)) & 1) != 0);
- }
-
-
- Boolean CSprite::OutOfBoundsQ()
- {
- Rect r;
-
- return !SectRect(&fLocation,GetGameBounds(),&r);
- }
-
-
- static Rect make_rect(GWorldPtr gWorld,short startTop,short startLeft)
- {
- Rect r;
- SetRect(&r,startLeft,startTop,startLeft,startTop);
-
-
- return r;
- }
-
- CPixMapSprite::CPixMapSprite(CSpriteWorld* world,long id,GWorldPtr image,
- short startTop,short startLeft,RgnHandle mask)
- : CSprite(world,id, make_rect(image,startTop,startLeft))
- {
- SetImage(image,mask);
- }
-
-
- void CPixMapSprite::Draw()//Override
-
- {
- if(fGWorld != NULL){
- Rect source = *GetLocation();
- OffsetRect(&source,-source.left,-source.top);
- GetWorld()->GetSpriteCanvas()->Blit(fPixMap, source, *GetLocation(), fSourceMask);
- }
- }
-
- void CPixMapSprite::SetImage(GWorldPtr image,RgnHandle mask)
- {
- fGWorld = image;
- fSourceMask = mask;
-
- if(fGWorld != NULL){
-
- fPixMap = GetGWorldPixMap(image);
- LockPixels(fPixMap);
-
- PixMapState pixMapState;
- LockPixMap(fPixMap,pixMapState);
-
- Rect imageSize = fPixMap[0]->bounds;
- Rect* me = GetLocation();
-
- me->right = me->left + RectWidth(imageSize);
- me->bottom = me->top + RectHeight(imageSize);
-
- }
- }
-
-
- CPixMapSprite::~CPixMapSprite()//Override
-
- {
-
- }
-
-
-
- CHPixMapSprite::CHPixMapSprite(CSpriteWorld* world,long id,GWorldPtr image,
- short startTop,short startLeft,RgnHandle mask)
- : CPixMapSprite( world,id, image, startTop, startLeft, mask)
- {
-
- }
-
-
- void CHPixMapSprite::UpdatePosition()//Override
- {
- OffsetRect(GetLocation(),5,0);
- if(GetLocation()->left > GetWorld()->GetSpriteCanvas()->GetBounds()->right){
- new CHPixMapSprite(GetWorld(), 0, fGWorld, GetLocation()->top+50, 0, NULL);
- delete this;
- }
- }
-
- CHPixMapSprite::~CHPixMapSprite()//Override
-
- {
-
- }
-
-
-
- void CSpriteCanvas::Blit(PixMapHandle pm,
- const Rect& inSourceRect,
- const Rect& inDestRect,
- RgnHandle inSourceMask)
- {
- GWorldPtr saveGWorld;
- GDHandle saveGD;
-
- ::GetGWorld(&saveGWorld,&saveGD);
- SetGWorld(fGWorld,NULL);
-
- if(inSourceMask != NULL){
- OffsetRgn(inSourceMask,inDestRect.left,inDestRect.top);
- }
-
- CopyBits((BitMap*)*pm, (BitMap*)*fPixMap, &inSourceRect, &inDestRect, srcCopy, inSourceMask);
-
- if(inSourceMask != NULL){
- OffsetRgn(inSourceMask,-inDestRect.left,-inDestRect.top);
- }
-
- SetGWorld(saveGWorld,saveGD);
- }
-
- void CSpriteCanvas::PrepareToDraw()
- {
- SetGWorld(fGWorld,NULL);
- }
-
-
-
- CSpriteCanvas::~CSpriteCanvas()
- {
-
- }
-
-
- CSpriteCanvas::CSpriteCanvas(OSErr& err)
- {
- fGWorld = NULL;
- GDHandle device = GetMainDevice();
- Rect bounds = device[0]->gdRect;
- err = NewGWorld(&fGWorld, 0,&bounds, NULL, NULL, 0);
- if(err == noErr){
- fPixMap = GetGWorldPixMap(fGWorld);
- LockPixels(fPixMap);
-
- PixMapState pixMapState;
- LockPixMap(fPixMap,pixMapState);
- fBounds = bounds;
-
-
- }
- }
-
-
- void CSpriteWorld::AddSprite(CSprite* sprite)
- {
- fSpriteQueue.Enqueue(sprite);
- }
-
-
- void CSpriteWorld::DrawAll()
- {
- DrawBackground();
- DrawSprites();
- Rect r = fCanvas->GetPixMap()[0]->bounds;
-
- StSaveGWorld save;
-
- SetGWorld(fCanvas->GetGWorld(),NULL);
- CopyBits((BitMap*)*fCanvas->GetPixMap(), (BitMap*)*fMainPixMap, &r, &r, srcCopy, NULL);
- }
-
-
- void CSpriteWorld::DrawBackground()
- {
- Rect source = *fBackground->GetBounds();
-
- fCanvas->Blit(fBackground->GetPixMap(),source, source, NULL);
- }
-
-
- void CSpriteWorld::DrawSprites()
- {
- TQIterator<CSprite> iter(fSpriteQueue);
-
- while(iter.MoreQ()){
- CSprite* thisSprite = iter.GetNext();
-
- thisSprite->Draw();
- }
- }
-
-
- void CSpriteWorld::ImageBackground(CSpriteCanvas* canvas)
- {
- StSaveGWorld save;
-
- fBackground->PrepareToDraw();
- BackColor(blackColor);
- EraseRect(fBackground->GetBounds());
- BackColor(whiteColor);
- }
-
-
- void CSpriteWorld::Idle()
- {
- UpdateSpriteLocations();
- CheckForHits();
- DrawAll();
- }
-
-
- CSpriteWorld::~CSpriteWorld()
- {
- Stop();
- RestorePixMap(fMainPixMap,fMainPixMapState);
- HSetState((Handle)GetMainDevice(),fDeviceState);
- }
-
-
- void CSpriteWorld::UpdateSpriteLocations()
- {
- TQIterator<CSprite> iter(fSpriteQueue);
-
- while(iter.MoreQ()){
- CSprite* thisOne = iter.GetNext();
-
- thisOne->UpdatePosition();
- }
- }
-
-
- CSpriteWorld::CSpriteWorld(OSErr& err)
- {
- err = noErr;
- fVBLInstalledQ = false;
-
- GDHandle device = GetMainDevice();
- fDeviceState = HGetState((Handle)device);
- HLock((Handle)device);
- fMainPixMap = device[0]->gdPMap;
- LockPixMap(fMainPixMap,fMainPixMapState);
- // lock it here
-
- fCanvas = new CSpriteCanvas(err);
- if(err == noErr){
- fBackground = new CSpriteCanvas(err);
- if(err == noErr){
- ImageBackground(fBackground);
- }
- }
-
- }
-
- void CSpriteWorld::_VBLTask()
- {
- ExtendedVBL* pb;
- long saveGlobals;
- short oldMemError = *(short *)0x220;
-
- pb = (ExtendedVBL*)GetA0();
- saveGlobals = GET_GLOBALS();
-
- SET_GLOBALS(pb->saveGlobals);
- StAllowDraw allowDraw;
-
- long oldA5 = pb->thisObj->fA5World.Use();
-
- pb->thisObj->Idle();
-
- pb->thisObj->fA5World.Restore(oldA5);
-
- // ##HACK##
- #ifdef __G_A4__
- if(LMGetCurApRefNum() <= 0){
- #endif
- pb->vblCount = kInterval;
- #ifdef __G_A4__
- }
- #endif
-
- *(short *)0x220 = oldMemError;
- SET_GLOBALS(saveGlobals);
- }
-
-
- void CSpriteWorld::InstallVBL()
- {
- if(!fVBLInstalledQ){
- fVBLInstalledQ = true;
-
- fVBL.qType = 1;
- fVBL.vblAddr = (VBLUPP)_VBLTask;
- fVBL.vblCount = kInterval;
- fVBL.vblPhase = 0;
- fVBL.saveGlobals = GET_GLOBALS();
- fVBL.thisObj = this;
-
- SlotVInstall((QElemPtr)&fVBL,GetMainSlot());
- }
- }
-
-
- void CSpriteWorld::RemoveVBL()
- {
- if(fVBLInstalledQ){
- fVBLInstalledQ = false;
- SlotVRemove((QElemPtr)&fVBL,GetMainSlot());
- }
- }
-
- void CSpriteWorld::CheckForHits()
- {
- TQIterator<CSprite> iter(fSpriteQueue);
-
- while(iter.MoreQ()){
- CSprite* thisOne = iter.GetNext();
-
- CheckForHitsOnThisSprite(thisOne);
- }
- }
-
-
- void CSpriteWorld::CheckForHitsOnThisSprite(CSprite* thisOne)
- {
- TQIterator<CSprite> iter(fSpriteQueue);
- Rect* r1;
- Rect* r2;
- Rect r3;
-
- r1 = thisOne->GetLocation();
- while(iter.MoreQ()){
- CSprite* test = iter.GetNext();
-
- if(test != thisOne){
- r2 = test->GetLocation();
- if(SectRect(r1,r2,&r3)){
- if(!test->WasHitBy(thisOne)){
- break;
- }
- }
- }
- }
- }
-
-
- void CSpriteWorld::RemoveSprite(CSprite* sprite)
- {
- fSpriteQueue.Dequeue(sprite);
- }
-
-
- void CSpriteWorld::Start()
- {
- InstallVBL();
- }
-
-
- void CSpriteWorld::Stop()
- {
- RemoveVBL();
- }
-
-
-
-
- StSaveGWorld::StSaveGWorld()
- {
- GetGWorld(&fSaveGWorld,&fSaveGD);
- }
-
-
- StSaveGWorld::~StSaveGWorld()
- {
- SetGWorld(fSaveGWorld,fSaveGD);
- }
-